#region Imported Namespaces
using System;
using System.Data;
using System.Data.SqlClient;
using System.Collections;

using BO = PHSRAG.Insight21.BusinessObjects;
using DataAccess = PHSRAG.Utility.DataAccess;
using ICachePolicy = PHSRAG.Insight21.Policy.ICachePolicy;

#endregion

namespace PHSRAG.Insight21.FormsManagement
{
	#region Class ItemProperty
	/// <summary>
	/// ItemProperty class abstracts the notion of an attribute to a question (QuestionnaireItem).
	/// Ex: A textbox question can have an attribute called TextMode which can be either SingleLine or MultiLine
	/// 
	/// Attributes/Properties for a checkbox, a radiobutton question, a dropdownlist etc are stored in 
	/// ItemProperty objects and are associated with their respective questions(QuestionnaireItem)
	/// </summary>
	public class ItemProperty : BO.SmartBusinessObject, ICloneable
	{
		#region Constants
		private const string QuestionnaireItemPropertyKey = "QuestionnaireItemPropertyKey_081BAE3F-359C-421e-AC42-5C538219F71E";
		private const string ColumnNameId = "Id";
		private const string ColumnNameItemId = "ItemId";
		private const string ColumnNameAttribute = "Attribute";
		private const string ColumnNameAttributeValue = "AttributeValue";
		#endregion

		#region Instance Variables (Private)
		private int questionnaireItemId;
		private string attributeName;
		private string attributeValue;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new ItemProperty object based on the Cache Policy passed in as a parameter. 
		/// </summary>
		/// <param name="cachePolicy">The prevalent cache policy</param>
		public ItemProperty(ICachePolicy cachePolicy) :  base(cachePolicy)
		{
		}
		
		
		/// <summary>
		/// Constructs a new ItemProperty object based on the Cache Policy passed in as a parameter. 
		/// All the instance variables will be set to the corresponding values specified in the Data Row
		/// </summary>
		/// <param name="cachePolicy">The prevalent cache policy</param>
		/// <param name="dataRow">DataRow holding the values to be assigned to instance variables</param>
		public ItemProperty(ICachePolicy cachePolicy, DataRow dataRow ) : base(cachePolicy)
		{
			Id	= (int)dataRow[ColumnNameId];
			questionnaireItemId = (int)dataRow[ColumnNameItemId];
			attributeName		= (string)dataRow[ColumnNameAttribute];
			attributeValue		= (string)dataRow[ColumnNameAttributeValue];
		}

		#endregion
		
        #region ICloneable
        object ICloneable.Clone()
        {
            return Clone();
        }
        #endregion

        public ItemProperty Clone()
        {
            ItemProperty property = (ItemProperty)MemberwiseClone( );
            property.Id = 0;
            property.Dirty = true;

            return property;
        }

        #region Properties
		/// <summary>
		/// Gets or sets the QuestionnaireItem id of the ItemProperty object
		/// </summary>
		public int QuestionnaireItemId
		{
			get	{ return questionnaireItemId; }
			set	{ SetDirty(ref questionnaireItemId, value);	}
		}


		/// <summary>
		/// Gets or sets the name of the Attribute
		/// </summary>
		public string AttributeName
		{
			get	{ return attributeName; }
			set	{ SetDirty(ref attributeName, value); }
		}

		
		/// <summary>
		/// Gets or sets the value for the Attribute
		/// </summary>
		public string AttributeValue
		{
			get	{ return attributeValue; }
			set	{ SetDirty(ref attributeValue, value); }
		}
		#endregion

		#region Smart Business Object Methods
		/// <summary>
		/// Cache Key uniquely identifies this object within the cache.
		/// </summary>
		/// <returns>the unique string for this object.</returns>
		public override string CacheKey()
		{
			return QuestionnaireItemPropertyKey;
		}
		
		
		/// <summary>
		/// Cache this instance using the prevalent cache policy.
		/// </summary>
		public override void Cache()
		{
			CachePolicy.Cache(QuestionnaireItemPropertyKey, this);
		}

		
		/// <summary>
		/// Remove this instance from the cache using the prevalent cache policy.
		/// </summary>
		public override void UnCache()
		{
			CachePolicy.UnCache(QuestionnaireItemPropertyKey);
		}

		
		/// <summary>
		///  Loads the ItemProperty based on the optional Args.
		/// <para>This method is not yet implemented</para> 
		/// </summary>
		/// <param name="connectionString">Information to connect to the database</param>
		/// <param name="args">ItemProperty Id of the object to be loaded</param>
		public override void Load(string connectionString, params object[] args)
		{
			throw new Exception("Not Implemented");
		}


		/// <summary>
		/// Saves the state of the ItemProperty object to the database. 
		/// The stored procedure inserts a new record if the id of the object is 0, 
		/// otherwise the procedure updates the record with the matching itemoption id
		/// </summary>
		/// <param name="sqlTransaction">The database context in which the underlying sql statement needs to be executed</param>
		protected override void SaveObject(SqlTransaction sqlTransaction)
		{
			try
			{
				Id = Convert.ToInt32(Utility.DataAccess.ExecuteScalar(sqlTransaction.Connection,sqlTransaction, "SaveItemProperty",
					Utility.DataAccess.BuildSqlParameterArray(
					"@id", SqlDbType.Int, Id
					,"@itemID", SqlDbType.Int, questionnaireItemId
					,"@attributeName", SqlDbType.VarChar, attributeName
					,"@attributeValue", SqlDbType.VarChar, attributeValue
					)));
			}
			catch(Exception ex)
			{
				Utility.ExceptionReport.WriteToEventLog("ItemProperty.SaveObject: Failed to save the ItemProperty object to the database", 
					ex, true, Utility.ExceptionReport.ReportType.Error);
				throw new Exception("ItemProperty.SaveObject: Failed to save the ItemProperty object to the database", ex);
			}
		}
		
		
		/// <summary>
		/// Deletes the record represented by the object
		/// </summary>
		/// <param name="sqlTransaction">SQL transaction to use when deleting</param>
		protected override void DeleteObject(SqlTransaction sqlTransaction)
		{
			try
			{
				Utility.DataAccess.ExecuteNonQuery(sqlTransaction.Connection,sqlTransaction, "DeleteItemProperty",
					Utility.DataAccess.BuildSqlParameterArray(
					"@id", SqlDbType.Int, Id));
			}
			catch(Exception ex)
			{
				Utility.ExceptionReport.WriteToEventLog("ItemProperty.DeleteObject: Failed to delete the ItemProperty object from the database", 
					ex, true, Utility.ExceptionReport.ReportType.Error);
				throw new Exception("ItemProperty.DeleteObject: Failed to delete the ItemProperty object from the database", ex);
			}
		}
		#endregion

		#region Static methods
		/// <summary>
		/// Gets all the Item Properties associated with a questionnaire item
		/// </summary>
		/// <param name="cachePolicy">The prevalent cache policy</param>
		/// <param name="itemID">QuestionnaireItem Id, the options of which have to be returned</param>
		/// <returns>A collection of ItemProperty objects</returns>
		public  static Hashtable GetQuestionnaireItemProperties(ICachePolicy cachePolicy, int itemID)
		{
			Hashtable propertiesList = new Hashtable();
			try
			{
				DataSet itemProperties = Utility.DataAccess.GetDataSet(Utility.DataAccess.GetConnectionString(), "GetItemPropertiesForItem",
					Utility.DataAccess.BuildSqlParameterArray
					("@ItemID", SqlDbType.Int, itemID));
				if (itemProperties.Tables.Count > 0)
				{
					foreach( DataRow row in itemProperties.Tables[0].Rows )
					{
						ItemProperty property = new ItemProperty(cachePolicy, row);
						propertiesList.Add(property.attributeName, property);
					}
				}
				else
				{
					throw new Exception("GetItemPropertiesForItem stored procedure returned incorrect results");
				}
			}
			catch(Exception ex)
			{
				Utility.ExceptionReport.WriteToEventLog ("ItemProperty.GetQuestionnaireItemProperties: Failed to load Questionnaire Item Properties", ex, true, Utility.ExceptionReport.ReportType.Error);
				throw new Exception("ItemProperty.GetQuestionnaireItemProperties: Failed to load Questionnaire Item Properties", ex);
			}

			return propertiesList;
		}
		#endregion
	}
	#endregion
}
